package user

import (
	"context"
	"fmt"
	"net/http"
	"wms/model"

	"wms/internal/svc"
	"wms/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type UpdateLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateLogic {
	return &UpdateLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UpdateLogic) Update(req *types.User) (resp *types.BaseResponse, err error) {
	resp = new(types.BaseResponse)

	if req.Id < 1 {
		resp.Code = http.StatusBadRequest
		resp.Msg = "请选择要修改的用户"
		return resp, nil
	}

	// 1.用户是否存在
	user, err := l.svcCtx.UserModel.FindOne(l.ctx, req.Id)
	switch err {
	case nil: //存在
	case model.ErrNotFound: //不存在
		fmt.Printf("[Error]用户[%d]不存在\n", req.Id)
		resp.Code = http.StatusBadRequest
		resp.Msg = "用户不存在"
		return resp, nil
	default: //其他错误
		fmt.Printf("[Error]查询用户[%d]是否存在:%s\n", req.Id, err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//2.用户名是否重复
	if user.Name != req.Name {
		_, err = l.svcCtx.UserModel.FindOneByName(l.ctx, req.Name)
		switch err {
		case nil: //存在
			fmt.Printf("[Error]查询用户名[%s]已存在\n", req.Name)
			resp.Code = http.StatusBadRequest
			resp.Msg = "用户名重复"
			return resp, nil
		case model.ErrNotFound: //不存在
		default: //其他错误
			fmt.Printf("[Error]查询用户名[%s]是否存在:%s\n", req.Name, err.Error())
			resp.Code = http.StatusInternalServerError
			resp.Msg = "服务内部错误"
			return resp, nil
		}

	}

	//3.手机号码是否重复
	if user.Mobile != req.Mobile {
		_, err = l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
		switch err {
		case nil: //存在
			fmt.Printf("[Error]查询用户手机号码[%s]已存在\n", req.Mobile)
			resp.Code = http.StatusBadRequest
			resp.Msg = "手机号码已占用"
			return resp, nil
		case model.ErrNotFound: //不存在
		default: //其他错误
			fmt.Printf("[Error]查询用户手机号码[%s]是否存在:%s\n", req.Mobile, err.Error())
			resp.Code = http.StatusInternalServerError
			resp.Msg = "服务内部错误"
			return resp, nil
		}
	}

	//4.部门是否存在
	_, err = l.svcCtx.DepartmentModel.FindOne(l.ctx, req.DepartmentId)
	switch err {
	case nil: //存在
	case model.ErrNotFound: //不存在
		fmt.Printf("[Error]部门[%d]不存在\n", req.DepartmentId)
		resp.Code = http.StatusBadRequest
		resp.Msg = "部门不存在"
		return resp, nil
	default: //其他错误
		fmt.Printf("[Error]查询部门[%d]是否存在:%s\n", req.DepartmentId, err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//4.角色是否存在
	for _, roleId := range req.RolesId {
		_, err = l.svcCtx.RoleModel.FindOne(l.ctx, roleId)
		switch err {
		case nil:
		case model.ErrNotFound:
			fmt.Printf("[Error]角色[%d]不存在\n", roleId)
			resp.Code = http.StatusBadRequest
			resp.Msg = "部分角色不存在"
			return resp, nil
		default:
			fmt.Printf("[Error]查询角色[%d]是否存在:%s\n", roleId, err.Error())
			resp.Code = http.StatusInternalServerError
			resp.Msg = "服务内部错误"
			return resp, nil
		}
	}

	//5.更新用户信息
	user.Name = req.Name
	user.Mobile = req.Mobile
	user.Status = req.Status
	user.DepartmentId = req.DepartmentId
	user.Remark = req.Remark

	err = l.svcCtx.UserModel.Update(l.ctx, user)
	if err != nil {
		fmt.Printf("[Error]修改用户[%d]失败:%s\n", req.Id, err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	//6.更新用户角色
	//TODO: casbin 更新用户的角色
	//var groupPolicies = make([][]string, 0)
	var roles []string
	for _, roleId := range req.RolesId {
		roles = append(roles, fmt.Sprintf("role_%d", roleId))
		//groupPolicies = append(groupPolicies, []string{fmt.Sprintf("user_%d", req.Id), fmt.Sprintf("role_%d", roleId)})
	}

	_, err = l.svcCtx.Enforcer.DeleteRolesForUser(fmt.Sprintf("user_%d", req.Id))
	if err != nil {
		fmt.Printf("[Error]用户[%d]清空角色:%s\n", req.Id, err.Error())
		resp.Code = http.StatusInternalServerError
		resp.Msg = "服务内部错误"
		return resp, nil
	}

	fmt.Println("给用户分配角色")
	if len(roles) > 0 {
		_, err = l.svcCtx.Enforcer.AddRolesForUser(fmt.Sprintf("user_%d", req.Id), roles)
		//_, err = l.svcCtx.Enforcer.AddNamedGroupingPolicies("g", groupPolicies)
		if err != nil {
			fmt.Printf("[Error]用户[%d]分配角色:%s\n", req.Id, err.Error())
			resp.Code = http.StatusInternalServerError
			resp.Msg = "服务内部错误"
			return resp, nil
		}
	}

	resp.Code = http.StatusOK
	resp.Msg = "成功"
	return resp, nil
}
